/*
 * @features: 功能
 * @description: https://docs.cocos.com/creator/2.4/api/zh/classes/Vec3.html
 * @Date: 2021-09-13 23:49:48
 * @Author: judu233(769471424@qq.com)
 * @LastEditTime: 2022-08-23 22:31:03
 * @LastEditors: judu233
 */
import { ExtendsLoad } from "../CCExtends";

/**扩展原型组件 */
@ExtendsLoad(cc.Vec3)
export class Vec3BaseExtends {
    /**
     * 随时间变化进度值
     * @param start  起始位置
     * @param end    结束位置
     * @param t      [0，1]
     * @returns 
    */
    static progress(start: cc.Vec3, end: cc.Vec3, t: number) {
        let current = new cc.Vec3();
        let progress = (start: number, end: number, t: number) => {
            return start + (end - start) * t;
        }
        current.x = progress(start.x, end.x, t);
        current.y = progress(start.y, end.y, t);
        current.z = progress(start.z, end.z, t);
        return current;
    }
    /**
     * 球面插值
     * @param from 
     * @param to 
     * @param t 
     * @returns 
     */
    static slerp(from: cc.Vec3, to: cc.Vec3, t: number): cc.Vec3 {
        if (t <= 0) {
            return from;
        }
        else if (t >= 1) {
            return to;
        }

        var dir: cc.Vec3 = this.rotateTo(from, to, (cc.Vec3.angle(from, to) / Math.PI * 180) * t);
        var lenght: number = to.len() * t + from.len() * (1 - t);

        return (dir.normalize()).multiplyScalar(lenght);
    }

    /**
     * 旋转
     * @param from 
     * @param to 
     * @param angle 
     */
    static rotateTo(from: cc.Vec3, to: cc.Vec3, angle: number): cc.Vec3 {
        //如果两个方向角度为0，则返回目标
        if (cc.Vec3.angle(from, to) == 0) {
            return to;
        }

        var axis: cc.Vec3 = new cc.Vec3()                 // 获得旋转轴
        cc.Vec3.cross(axis, from, to);
        axis.normalize();

        var radian: number = angle * Math.PI / 180; // 获得弧度
        var rotateMatrix: cc.Mat4 = new cc.Mat4();
        rotateMatrix.rotate(radian, axis);

        // return new cc.Vec3(
        //     from.x * rotateMatrix.m00 + from.y * rotateMatrix.m04 + from.z * rotateMatrix.m08,
        //     from.x * rotateMatrix.m01 + from.y * rotateMatrix.m05 + from.z * rotateMatrix.m09,
        //     from.x * rotateMatrix.m02 + from.y * rotateMatrix.m06 + from.z * rotateMatrix.m10
        // );
    }
}
/**扩展组件实例方法 */
@ExtendsLoad(cc.Vec3.prototype)
export class Vec3Extends {

    /**
     * 重载 * 运算符
     * @param other 
     * @returns 
     */
    static mtimes(other: cc.Vec3 | number) {
        let selfVec3 = this as any as cc.Vec3;
        if (typeof (other) == "number") {
            return new cc.Vec3(selfVec3.x * other, selfVec3.y * other, selfVec3.z * other);
        } else {
            return new cc.Vec3(selfVec3.x * other.x, selfVec3.y * other.y, selfVec3.z * other.z);
        }
    }

    /**
     * 重载 + 运算符
     * @param other 
     * @returns 
     */
    static plus(other) {
        let selfVec3 = this as any as cc.Vec3;
        if (typeof (other) == "number") {
            return new cc.Vec3(selfVec3.x + other, selfVec3.y + other, selfVec3.z + other)
        } else {
            return new cc.Vec3(selfVec3.x + other.x, selfVec3.y + other.y, selfVec3.z + other.z)
        }
    }

    /**把当前vect3转换成vect2,注意会丢失z轴 */
    static toV2() {
        let v = this as any as cc.Vec3;
        return new cc.Vec2(v.x, v.y);
    }

    /**把当前vect3转换成vect4, 不足的填充0 */
    static toV4() {
        let v = this as any as cc.Vec3;
        return new cc.Vec4(v.x, v.y, v.z);
    }

    static toSize() {
        let v = this as any as cc.Vec3;
        return new cc.Size(v.x, v.y);
    }

    static toRect() {
        let v = this as any as cc.Vec3;
        return new cc.Rect(v.x, v.y);
    }

    /** x取反 */
    static negationX() {
        let p: cc.Vec3 = this as any;
        return cc.v3(-p.x, p.y, p.z);
    }

    /** y取反 */
    static negationY() {
        let p: cc.Vec3 = this as any;
        return cc.v3(p.x, -p.y, p.z);
    }

    /** z取反 */
    static negationZ() {
        let p: cc.Vec3 = this as any;
        return cc.v3(p.x, p.y, - p.z);
    }

    /**压缩x轴为0 */
    static compresseX() {
        let p: cc.Vec3 = this as any;
        return cc.v3(0, p.y, p.z);
    }

    /**压缩y轴为0 */
    static compresseY() {
        let p: cc.Vec3 = this as any;
        return cc.v3(p.x, 0, p.z);
    }

    /**压缩z轴为0 */
    static compresseZ() {
        let p: cc.Vec3 = this as any;
        return cc.v3(p.x, p.y, 0);
    }

    /**
     * 返回当前矩形的字符串表示。
     * @returns 
     */
    static print() {
        let self = this as any as cc.Vec3;
        return `(${self.x.toFixed(2)}, ${self.y.toFixed(2)}, ${self.z.toFixed(2)})`;
    }
}
